package trb.complexshield.voxel;

import java.awt.Color;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.TransformGroup;
import no.hrp.hvrc.property.editor.AppearanceProperties;
import no.hrp.hvrc.property.editor.SetDirectly;
import no.hrp.hvrc.utils.j3d.BBox;
import no.hrp.hvrc.utils.j3d.Mat4;
import no.hrp.hvrc.utils.j3d.ObjectViewer;
import no.hrp.hvrc.utils.j3d.SGUtils;
import no.hrp.hvrc.utils.j3d.Vec3;
import no.hrp.hvrc.utils.j3d.geometry.ResizableBox;
import trb.complexshield.benchmarking.SegmentsBenchmark;

public class VoxelVisualisation {

    private VoxelGridBox voxelGridBox;
    private final TransformGroup tg = SGUtils.createTransformGroup();
    public final BranchGroup rootBG = SGUtils.wrapInBrancGroup(tg);

    public VoxelVisualisation(VoxelGridBox box, Object boolModel) {
        this.voxelGridBox = box;

        AppearanceProperties properties = new AppearanceProperties(null, new SetDirectly(), null);
        properties.diffuse.set(Color.RED);
        properties.transparancyEnabled.set(true);
        properties.transparancy.set(0.5f);
        Appearance appearance = properties.createNewAppearance();

        BranchGroup bg = SGUtils.createBranchGroup();
        VoxelGrid grid = box.voxelGrid;
        for (int zIdx=0; zIdx<grid.zdim; zIdx++) {
            for (int yIdx=0; yIdx<grid.ydim; yIdx++) {
                for (int xIdx = 0; xIdx < grid.xdim; xIdx++) {
                    if (grid.getBitAtIndex(xIdx, yIdx, zIdx)) {
                        ResizableBox resizableBox = new ResizableBox();
                        resizableBox.setBounds(new BBox(new Vec3(xIdx, yIdx, zIdx), new Vec3(xIdx+1, yIdx+1, zIdx+1)));
                        resizableBox.setAppearance(appearance);
                        bg.addChild(resizableBox.getRootBG());
                    }
                }
            }
        }
        Mat4 mat4 = new Mat4();
        mat4.mul_(box.intersectableBox.getLocalToWorld());
        float[] minMax = box.intersectableBox.getMinMax();
        mat4.translate(minMax[0], minMax[1], minMax[2]);
        mat4.scale((minMax[3] - minMax[0]), (minMax[4] - minMax[1]), (minMax[5] - minMax[2]));
        mat4.scale(1.0 / grid.xdim, 1.0 / grid.ydim, 1.0 / grid.zdim);

        if (false) {
            ResizableBox resizableBox = new ResizableBox();
            resizableBox.setBounds(new BBox(new Vec3(), new Vec3(grid.xdim, grid.ydim, grid.zdim)));
            resizableBox.setAppearance(appearance);
            tg.addChild(SGUtils.createTransformGroup(mat4, resizableBox.getRootBG()));
        }

        tg.addChild(SGUtils.createTransformGroup(mat4, bg));

//        Vec3 min = new Vec3(-2, 0, -2);
//        Vec3 max = new Vec3( 2, 4,  2);
//        float[] measurePositions = SegmentsBenchmark.createMeasurePositions(min, max, 1f);
//        float[] sourcePositions = SegmentsBenchmark.createSourcePositions(min, max, 10);//{0, 0.5f, 0};
//        SegmentsBenchmark segmentsBenchmark = new SegmentsBenchmark(measurePositions, sourcePositions);
//
//        BenchmarkShieldSet set = new BenchmarkShieldSet();
//        set.add(BenchmarkTub.createComplexShieldFromBoolModel(boolModel), "boolean");
//        set.add(box, "voxel");
//
//        List<SegmentOutput> segmentOutputList = segmentsBenchmark.benchmarkCorrectness(set);
//        GeometryArray intersectionVisualisation = segmentsBenchmark.createIntersectionVisualisation(segmentOutputList);

//        rootBG.addChild(new Shape3D(intersectionVisualisation));
    }

    public static void main(String[] args) {
        Object boolModel = SegmentsBenchmark.createBoolModel();
        VoxelGridBox voxelGridBox = VoxelFromBool.createVoxel(boolModel, 8);
        ObjectViewer.view(new VoxelVisualisation(voxelGridBox, boolModel).rootBG);
    }
}
